iT邦幫忙

2022 iThome 鐵人賽

DAY 22
2
自我挑戰組

PixelBit 可以這樣玩!系列 第 22

(Day 22)Arduino 簡化上下位機通訊(Part 2)

  • 分享至 

  • xImage
  •  

昨天說到上下位機通訊的概念,以及假設了應用情境,並且根據期望長出最終應用上的程式碼,今天將會說明 CircusUart Library 各個 API 以及使用方式。

初始化物件

在一開始需要先建立 CircusUart 物件,並且在 Constructor 中帶入需要發送的 Serial Object Reference,並且需要自行在 Setup 方法中初始化並設定 Baudrate。

CircusUart uart(Serial);
void setup()
{
    Serial.begin(57600);
}

接收資料

CircusUart 使用非同步的方式接收並處理資料,使用者需要先在初始化時設定好需要接收的命令以及分隔符號,例如,當接收到溫度資料時判斷溫度是否大於 30 度,若大於 30 度則開啟風扇,設定需使用 on 方法,參數分別為:收到的命令開頭標記(Temp)、資料中間的分隔字元(:)、收到此筆資料要呼叫的方法,例如:

void setup()
{
    Serial.begin(57600);

    uart.on("Temp", ':', [](const char *temp) {
        if(atoi(temp) > 30) {
            digitalWrite(FAN_PIN, HIGH);
        }
    });
}

並且需要再 Arduinio Loop 方法內不斷輪詢檢查是否有資料進來

void loop()
{
    uart.loop();
}

發送資料

假設另一端每秒發送溫度資料,發送使用 send 方法,參數分別為:開頭標記(Temp)、資料中間的分隔字元(:)、要發送的資料內容(30.5)。

void loop()
{
    static uint32_t timer = 0;
    if (millis() > timer) {
        timer = millis() + 1000;
        uart.send("Temp", ':', "30.5");
    }
}

使用起來就是這麼簡單~這樣我們只需要預先設定好雙方的資料標籤以及分隔字元,就可以很方便的將上下位機串連起來通訊了。

CircusUart Library 說明

CircusUart.h 內部定義了 命令處理程序的最大數量(CIRCUS_HANDLER_MAX),此數值代表可註冊的命令數量,預設為16組,越多越佔記憶體,需要根據開發板適時調整;接收資料 Buffer長度(CIRCUS_RX_BUFF)預設為 32 Byte,若需傳輸的資料更長則需要調整此數值。

#define CIRCUS_HANDLER_MAX 16
#define CIRCUS_RX_BUFF 32

CircusUart Class Method 與 Member

class CircusUart : public Print {
  private:
    Stream   &stream;
    uint8_t   receive(void);
    handler_t handlers[CIRCUS_HANDLER_MAX];
    uint8_t   handler_idx;
    char      rec_buff[CIRCUS_RX_BUFF];

  public:
    CircusUart(Stream &stream);
    ~CircusUart();
    void     loop();
    uint16_t send(const char *cmd, const char separator = '\0', const char *param = NULL);
    void     on(const char *cmd, const char separator, Func func);
    size_t   write(uint8_t);
    size_t   write(const char *buffer, size_t size);
};

我們將 CircusUart Class 繼承自 Arduino 內建 Print,所以一般 Serial 物件可以呼叫的方法 CircusUart 也能使用,如果使用的開發板核心有完整支援 C 語言 Stdio 則可以很方便的使用像是 printf 這類指令,讓發送資料更方便,例如:

uart.printf("Temp:%d", 30.5);

CircusUart.cpp 為每個方法的實作,內容較多就不過多說明,有興趣可以自行參考,目前CircusUart Library 只是初階版,只有簡單的傳送與接收,未來還會繼續加入其他常用功能,像是優先權,超時處理,使用 FreeRTOS 等等,讓我們使用 UART 通訊能更加方便且提高穩定性與效率,讓我們一起讓程式碼變得跟 Python 一樣簡潔吧~~。

更多有趣系列教學文章


上一篇
(Day 21)Arduino 簡化上下位機通訊(Part 1)
下一篇
(Day 23)FPV RockBot 洛克霸
系列文
PixelBit 可以這樣玩!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言